import time
import threading
from collections import defaultdict, deque
from datetime import datetime, timedelta, timezone
import logging
from typing import Dict, List, Optional

class APIMonitor:
    def __init__(self):
        self.usage_stats = defaultdict(lambda: {
            'requests': deque(maxlen=1000),
            'errors': deque(maxlen=1000),
            'total_requests': 0,
            'total_errors': 0
        })
        self.rate_limits = {}
        self.health_status = {}
        self.lock = threading.Lock()
        
    def record_request(self, provider: str, success: bool, response_time: float):
        """记录API请求"""
        with self.lock:
            stats = self.usage_stats[provider]
            timestamp = time.time()
            
            stats['requests'].append((timestamp, response_time))
            stats['total_requests'] += 1
            
            if not success:
                stats['errors'].append(timestamp)
                stats['total_errors'] += 1
            
            # 清理过期记录（>1h）
            current_time = time.time()
            stats['requests'] = deque(
                [r for r in stats['requests'] if current_time - r[0] < 3600],
                maxlen=1000
            )
            stats['errors'] = deque(
                [e for e in stats['errors'] if current_time - e < 3600],
                maxlen=1000
            )
    
    def get_usage_stats(self, provider: str, time_window: int = 3600) -> Dict:
        """获取使用统计"""
        stats = self.usage_stats[provider]
        current_time = time.time()
        
        recent_requests = [r for r in stats['requests'] if current_time - r[0] < time_window]
        recent_errors = [e for e in stats['errors'] if current_time - e < time_window]
        
        if recent_requests:
            avg_response_time = sum(r[1] for r in recent_requests) / len(recent_requests)
        else:
            avg_response_time = 0
        
        return {
            'total_requests': stats['total_requests'],
            'total_errors': stats['total_errors'],
            'recent_requests': len(recent_requests),
            'recent_errors': len(recent_errors),
            'error_rate': len(recent_errors) / max(len(recent_requests), 1),
            'avg_response_time': avg_response_time,
            'requests_per_minute': len(recent_requests) / max(time_window / 60, 1)
        }
    
    def check_rate_limit(self, provider: str, identifier: str) -> bool:
        """检查速率限制"""
        key = f"{provider}:{identifier}"
        current_time = time.time()
        
        if key not in self.rate_limits:
            self.rate_limits[key] = deque(maxlen=100)
        
        requests = self.rate_limits[key]
        
        # 清理过期请求（>1m）
        requests = deque([r for r in requests if current_time - r < 60], maxlen=100)
        self.rate_limits[key] = requests
        
        # 检查是否超过限制（60次/m）
        provider_config = self.get_provider_config(provider)
        limit = provider_config.get('rate_limit', 60)
        
        return len(requests) < limit
    
    def record_rate_limit(self, provider: str, identifier: str):
        """记录速率限制使用"""
        key = f"{provider}:{identifier}"
        if key not in self.rate_limits:
            self.rate_limits[key] = deque(maxlen=100)
        
        self.rate_limits[key].append(time.time())
    
    def update_health_status(self, provider: str, status: bool, message: str = ""):
        """更新健康状态"""
        self.health_status[provider] = {
            'status': status,
            'message': message,
            'last_check': datetime.now(timezone.utc),
            'response_time': time.time()
        }
    
    def get_health_status(self, provider: str) -> Dict:
        """获取健康状态"""
        status = self.health_status.get(provider, {
            'status': False,
            'message': 'Not monitored',
            'last_check': None,
            'response_time': 0
        })
        
        # 检查是否状态过期（>5m）
        if status['last_check']:
            time_diff = datetime.now(timezone.utc) - status['last_check']
            if time_diff > timedelta(minutes=5):
                status['status'] = False
                status['message'] = 'Status outdated'
        
        return status